package service

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"sync"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay"
	"gorm.io/gorm"
)

// WebhookService webhook服务
// 用于处理来自PhotonPay的webhook通知
type WebhookService struct {
	photonClient *photonpay.PhotonPayClient
	// 用于存储已处理的交易ID，防止重复处理
	processedTransactions sync.Map
}

// NewWebhookService 创建webhook服务实例
// 参数:
//   - photonClient: PhotonPay客户端实例
//
// 返回:
//   - *WebhookService: webhook服务实例
func NewWebhookService(photonClient *photonpay.PhotonPayClient) *WebhookService {
	return &WebhookService{
		photonClient: photonClient,
	}
}

// WebhookNotification webhook通知结构体
// 用于解析和处理webhook通知数据
type WebhookNotification struct {
	TransactionID   string                 `json:"transactionId"`   // 交易ID
	CardID          string                 `json:"cardId"`          // 卡ID
	CardStatus      string                 `json:"cardStatus"`      // 卡状态
	TransactionType string                 `json:"transactionType"` // 交易类型
	MatrixAccount   string                 `json:"matrixAccount"`   // 矩阵账户
	Amount          float64                `json:"amount"`          // 金额
	Currency        string                 `json:"currency"`        // 货币
	Status          string                 `json:"status"`          // 状态
	RawData         map[string]interface{} `json:"-"`               // 原始数据
}

// HLWebhookNotification 海连webhook通知结构体
type HLWebhookNotification struct {
	Msg       string                 `json:"msg"`       // 消息
	Data      HLWebhookData          `json:"data"`      // 数据
	EventType string                 `json:"eventType"` // 事件类型
	ID        string                 `json:"id"`        // ID
	Status    string                 `json:"status"`    // 状态
	RawData   map[string]interface{} `json:"-"`         // 原始数据
}

// HLWebhookData 海连webhook数据
type HLWebhookData struct {
	Amount              float64     `json:"amount"`              // 结算金额
	Currency            string      `json:"currency"`            // 结算币种
	TransactionAmount   float64     `json:"transactionAmount"`   // 交易金额
	TransactionCurrency string      `json:"transactionCurrency"` // 交易币种
	Fee                 float64     `json:"fee"`                 // 手续费
	TransactionNo       string      `json:"transactionNo"`       // 交易流水号
	ClientTransactionID string      `json:"clientTransactionId"` // 客户端号
	TransactionTime     json.Number `json:"transactionTime"`     // 交易时间（时间戳）
	CardNo              string      `json:"cardNo"`              // 交易卡号
	TransactionType     string      `json:"transactionType"`     // 交易类型
	CardID              json.Number `json:"cardId"`              // 卡号（JSON中是数字类型）
	Detail              string      `json:"detail"`              // 交易详情
	ID                  json.Number `json:"id"`                  // 交易ID（JSON中是数字类型）
	Status              string      `json:"status"`              // 交易状态
	Remark              string      `json:"remark,omitempty"`    // 备注（可选）
}

// ProcessWebhook 处理webhook通知
// 参数:
//   - params: 请求参数
//   - signature: 签名
//   - notificationCategory: 通知类别
//   - notificationType: 通知类型
//
// 返回:
//   - error: 处理过程中的错误
func (s *WebhookService) ProcessWebhook(params map[string]interface{}, signature string, notificationCategory, notificationType string) error {
	log.Printf("[Webhook] 收到通知: 类别=%s, 类型=%s", notificationCategory, notificationType)

	// 1. 验证签名
	// TODO: 验证签名 开发暂时关闭
	// if signature != "" && !s.photonClient.VerifySign(params, signature) {
	// 	return fmt.Errorf("签名无效")
	// }

	// 2. 检查重复处理
	if transactionID, ok := params["transactionId"].(string); ok {
		if _, exists := s.processedTransactions.Load(transactionID); exists {
			return fmt.Errorf("重复的交易ID: %s", transactionID)
		}
		s.processedTransactions.Store(transactionID, time.Now())
	}

	// 3. 解析通知数据
	var notification WebhookNotification
	notification.RawData = params
	jsonData, err := json.Marshal(params)
	if err != nil {
		return fmt.Errorf("参数序列化失败: %v", err)
	}
	if err := json.Unmarshal(jsonData, &notification); err != nil {
		return fmt.Errorf("通知反序列化失败: %v", err)
	}

	// 4. 创建webhook通知记录
	webhookRecord := &models.WebhookNotification{
		NotificationType: notificationType,
		TransactionID:    notification.TransactionID,
		CardID:           notification.CardID,
		MatrixAccount:    notification.MatrixAccount,
		Platform:         "photonpay",
		Category:         notificationCategory,
		RawData:          notification.RawData,
		ProcessedAt:      time.Now(),
		Status:           "processed",
	}

	if err := database.DB.Create(webhookRecord).Error; err != nil {
		return fmt.Errorf("创建webhook通知记录失败: %v", err)
	}

	// 5. 获取用户ID
	var user models.User
	if err := database.DB.Where("matrix_account = ?", notification.MatrixAccount).First(&user).Error; err != nil {
		log.Printf("[Webhook] 警告: 未找到用户 matrix_account=%s", notification.MatrixAccount)
		return nil // 继续处理，不返回错误
	}

	// 6. 创建用户通知
	if err := s.createUserNotification(user.ID, notificationCategory, notificationType, notification); err != nil {
		log.Printf("[Webhook] 警告: 创建用户通知失败: %v", err)
	}

	// 7. 处理特定类型的通知
	switch notificationCategory {
	case "issuing_card":
		return s.handleCardStatusUpdate(notification)
	case "issuing":
		return s.handleCardTransaction(notification)
	case "issuing_settlement":
		return s.handleCardSettlement(notificationType, notification)
	case "global_account":
		return s.handleGlobalAccount(notificationType, notification)
	}

	return nil
}

// createUserNotification 创建用户通知
func (s *WebhookService) createUserNotification(userID int64, category, notificationType string, notification WebhookNotification) error {
	// 获取通知类型ID
	var notificationTypeModel models.NotificationType
	if err := database.DB.Where("code = ?", notificationType).First(&notificationTypeModel).Error; err != nil {
		return fmt.Errorf("获取通知类型失败: %v", err)
	}

	// 构建通知内容
	title, content := s.buildNotificationContent(category, notificationType, notification)

	// 将 RawData 转换为 JSON
	jsonData, err := json.Marshal(notification.RawData)
	if err != nil {
		return fmt.Errorf("序列化通知数据失败: %v", err)
	}

	// 创建通知记录
	userNotification := &models.Notification{
		UserID:    int64(userID),
		TypeID:    int64(notificationTypeModel.ID),
		Title:     title,
		Content:   content,
		Data:      models.JSON(jsonData),
		Status:    "UNREAD",
		CreatedAt: time.Now(),
	}

	return database.DB.Create(userNotification).Error
}

// buildNotificationContent 构建通知内容
func (s *WebhookService) buildNotificationContent(category, notificationType string, notification WebhookNotification) (string, string) {
	var title, content string

	switch category {
	case "issuing_card":
		title = "卡片状态更新"
		content = fmt.Sprintf("卡片 %s 状态已更新为 %s", notification.CardID, notification.CardStatus)
	case "issuing":
		title = "交易通知"
		content = fmt.Sprintf("交易类型: %s, 金额: %.2f %s", notification.TransactionType, notification.Amount, notification.Currency)
	case "issuing_settlement":
		title = "结算通知"
		content = fmt.Sprintf("结算类型: %s, 金额: %.2f %s", notificationType, notification.Amount, notification.Currency)
	case "global_account":
		title = "账户通知"
		content = fmt.Sprintf("账户状态更新: %s", notification.Status)
	default:
		title = "系统通知"
		content = fmt.Sprintf("收到新的通知: %s", notificationType)
	}

	return title, content
}

// handleCardStatusUpdate 处理卡状态更新
func (s *WebhookService) handleCardStatusUpdate(notification WebhookNotification) error {
	// 更新卡状态
	if notification.CardStatus == "cancelled" {
		log.Printf("[Webhook] 处理卡注销状态: %s", notification.CardID)
		// 记录卡状态变更历史
		err := database.DB.Create(&models.CardStatusHistory{
			CardID:    notification.CardID,
			NewStatus: notification.CardStatus,
			ChangedAt: time.Now(),
			ChangedBy: "system",
			Reason:    "Card cancelled via webhook",
		}).Error
		if err != nil {
			log.Printf("[Webhook] 记录卡状态历史失败: %v", err)
		}
	}

	// 更新数据库中的卡状态
	err := database.DB.Model(&models.UserCard{}).
		Where("card_id = ?", notification.CardID).
		Update("status", notification.CardStatus).Error
	if err != nil {
		log.Printf("[Webhook] 更新卡状态失败: %v", err)
		return fmt.Errorf("更新卡状态失败: %v", err)
	}

	return nil
}

// handleCardTransaction 处理卡交易
func (s *WebhookService) handleCardTransaction(notification WebhookNotification) error {
	// 创建交易记录
	err := database.DB.Create(&models.Transaction{
		TransactionID:   notification.TransactionID,
		CardID:          notification.CardID,
		TransactionType: notification.TransactionType,
		Amount:          notification.Amount,
		Currency:        notification.Currency,
		Status:          notification.Status,
		MatrixAccount:   notification.MatrixAccount,
		Platform:        "photonpay",
		RawData:         notification.RawData,
		ProcessedAt:     time.Now(),
	}).Error
	if err != nil {
		log.Printf("[Webhook] 创建交易记录失败: %v", err)
		return fmt.Errorf("创建交易记录失败: %v", err)
	}

	return nil
}

// handleGlobalAccount 处理全局账户通知
func (s *WebhookService) handleGlobalAccount(notificationType string, notification WebhookNotification) error {
	switch notificationType {
	case "apply":
		// 处理申请通知
		return s.handleGlobalAccountApply(notification)
	case "close":
		// 处理注销通知
		return s.handleGlobalAccountClose(notification)
	case "settle":
		// 处理入账通知
		return s.handleGlobalAccountSettle(notification)
	default:
		return fmt.Errorf("未知的全局账户通知类型: %s", notificationType)
	}
}

// handleGlobalAccountApply 处理全局账户申请通知
func (s *WebhookService) handleGlobalAccountApply(notification WebhookNotification) error {
	// 创建通知记录
	err := database.DB.Create(&models.WebhookNotification{
		NotificationType: "global_account_apply",
		TransactionID:    notification.TransactionID,
		MatrixAccount:    notification.MatrixAccount,
		Platform:         "photonpay",
		Category:         "global_account",
		RawData:          notification.RawData,
		ProcessedAt:      time.Now(),
		Status:           "processed",
	}).Error
	if err != nil {
		log.Printf("[Webhook] 创建全局账户申请通知记录失败: %v", err)
		return fmt.Errorf("创建全局账户申请通知记录失败: %v", err)
	}

	// 更新用户状态
	if notification.Status == "success" {
		err = database.DB.Model(&models.User{}).
			Where("matrix_account = ?", notification.MatrixAccount).
			Update("status", "active").Error
		if err != nil {
			log.Printf("[Webhook] 更新用户状态失败: %v", err)
			return fmt.Errorf("更新用户状态失败: %v", err)
		}
	}

	return nil
}

// handleGlobalAccountClose 处理全局账户注销通知
func (s *WebhookService) handleGlobalAccountClose(notification WebhookNotification) error {
	// 创建通知记录
	err := database.DB.Create(&models.WebhookNotification{
		NotificationType: "global_account_close",
		TransactionID:    notification.TransactionID,
		MatrixAccount:    notification.MatrixAccount,
		Platform:         "photonpay",
		Category:         "global_account",
		RawData:          notification.RawData,
		ProcessedAt:      time.Now(),
		Status:           "processed",
	}).Error
	if err != nil {
		log.Printf("[Webhook] 创建全局账户注销通知记录失败: %v", err)
		return fmt.Errorf("创建全局账户注销通知记录失败: %v", err)
	}

	// 更新用户状态
	if notification.Status == "success" {
		err = database.DB.Model(&models.User{}).
			Where("matrix_account = ?", notification.MatrixAccount).
			Update("status", "closed").Error
		if err != nil {
			log.Printf("[Webhook] 更新用户状态失败: %v", err)
			return fmt.Errorf("更新用户状态失败: %v", err)
		}
	}

	return nil
}

// handleGlobalAccountSettle 处理全球账户结算通知
func (s *WebhookService) handleGlobalAccountSettle(notification WebhookNotification) error {
	log.Printf("[Webhook] 处理全球账户结算: %+v", notification)

	// 幂等性检查：检查是否已经处理过这个结算通知
	// 根据关键信息（MatrixAccount, Amount, Status, 和一个时间窗口）来判断
	var existingNotification models.WebhookNotification
	queryTime := time.Now().Add(-24 * time.Hour) // 假设24小时内的重复通知为同一个
	err := database.DB.Where("matrix_account = ? AND category = 'global_account' AND notification_type = 'settle' AND raw_data->>'$.amount' = ? AND created_at > ?",
		notification.MatrixAccount,
		notification.Amount,
		queryTime).First(&existingNotification).Error

	if err == nil {
		// 已经存在相似的通知，认为是重复的
		log.Printf("[Webhook] 检测到重复的结算通知，跳过处理: %+v", notification)
		return nil
	}

	// 创建结算通知记录
	err = database.DB.Create(&models.WebhookNotification{
		NotificationType: "global_account_settle",
		TransactionID:    notification.TransactionID,
		MatrixAccount:    notification.MatrixAccount,
		Platform:         "photonpay",
		Category:         "global_account",
		RawData:          notification.RawData,
		ProcessedAt:      time.Now(),
		Status:           "processed",
	}).Error
	if err != nil {
		log.Printf("[Webhook] 创建全局账户结算通知记录失败: %v", err)
		return fmt.Errorf("创建全局账户结算通知记录失败: %v", err)
	}

	return nil
}

// handleCardSettlement 处理卡结算通知
func (s *WebhookService) handleCardSettlement(notificationType string, notification WebhookNotification) error {
	// 创建结算记录
	err := database.DB.Create(&models.Settlement{
		TransactionID:  notification.TransactionID,
		CardID:         notification.CardID,
		SettlementType: notificationType,
		Amount:         notification.Amount,
		Currency:       notification.Currency,
		Status:         notification.Status,
		MatrixAccount:  notification.MatrixAccount,
		Platform:       "photonpay",
		RawData:        notification.RawData,
		SettledAt:      time.Now(),
	}).Error
	if err != nil {
		log.Printf("[Webhook] 创建结算记录失败: %v", err)
		return fmt.Errorf("创建结算记录失败: %v", err)
	}

	return nil
}

// ProcessHLWebhook 处理海连webhook通知
// 海连webhook只处理交易详情记录，不涉及余额更新和开卡处理
// 参数:
//   - params: 请求参数
//   - signature: 签名（可选）
//
// 返回:
//   - error: 处理过程中的错误
func (s *WebhookService) ProcessHLWebhook(params map[string]interface{}, signature string) error {
	log.Printf("[HL Webhook] 收到通知: %+v", params)

	// 1. 验证签名（如果需要）
	// TODO: 验证签名 开发暂时关闭
	// if signature != "" && !s.verifyHLSign(params, signature) {
	// 	return fmt.Errorf("签名无效")
	// }

	// 2. 检查重复处理
	if id, ok := params["id"].(string); ok {
		if _, exists := s.processedTransactions.Load(id); exists {
			return fmt.Errorf("重复的通知ID: %s", id)
		}
		s.processedTransactions.Store(id, time.Now())
	}

	// 2.5 根据eventType判断data格式
	eventType, _ := params["eventType"].(string)
	if data, ok := params["data"]; ok {
		if eventType == "open:card" {
			// 开卡通知，data为数字或仅包含cardId
			switch v := data.(type) {
			case float64, int, int64, json.Number:
				cardID := fmt.Sprintf("%v", v)
				params["data"] = map[string]interface{}{
					"cardId": cardID,
				}
			}
		}
	}

	// 3. 解析通知数据
	var notification HLWebhookNotification
	notification.RawData = params
	jsonData, err := json.Marshal(params)
	if err != nil {
		return fmt.Errorf("参数序列化失败: %v", err)
	}
	decoder := json.NewDecoder(bytes.NewReader(jsonData))
	decoder.UseNumber()
	if err := decoder.Decode(&notification); err != nil {
		return fmt.Errorf("通知反序列化失败: %v", err)
	}

	// 4. 获取用户ID和MatrixAccount（通过卡片ID查找）
	var userCard models.UserCard
	var matrixAccount string
	cardIDStr := notification.Data.CardID.String()
	if err := database.DB.Where("card_id = ?", cardIDStr).First(&userCard).Error; err != nil {
		log.Printf("[HL Webhook] 警告: 未找到卡片 card_id=%s", cardIDStr)
		matrixAccount = "" // 如果找不到卡片，matrix_account为空
	} else {
		// 通过user_id查找MatrixAccount
		var userMatrixAccount models.UserMatrixAccount
		if err := database.DB.Where("user_id = ?", userCard.UserID).First(&userMatrixAccount).Error; err != nil {
			log.Printf("[HL Webhook] 警告: 未找到用户矩阵账户 user_id=%d", userCard.UserID)
			matrixAccount = ""
		} else {
			matrixAccount = userMatrixAccount.MatrixAccount
		}
	}

	log.Printf("[HL Webhook] 接收到webhook: 事件类型=%s, 交易ID=%s, 卡ID=%s, 矩阵账户=%s",
		notification.EventType, notification.Data.TransactionNo, cardIDStr, matrixAccount)

	// 5. 根据事件类型处理不同的通知
	switch notification.EventType {
	case "transaction:consumption":
		return s.handleHLTransaction(notification, "消费")
	case "transaction:refund":
		return s.handleHLTransaction(notification, "退款")
	case "transaction:protest":
		return s.handleHLTransaction(notification, "拒付")
	case "transaction:reversal":
		return s.handleHLTransaction(notification, "撤销")
	case "transaction:transferin":
		return s.handleHLTransaction(notification, "转入")
	case "transaction:transferout":
		return s.handleHLTransaction(notification, "转出")
	case "transaction:credit":
		return s.handleHLTransaction(notification, "授权")
	case "open:card":
		log.Printf("[HL Webhook] 处理开卡事件: 卡ID=%s", cardIDStr)
		// 1. 查找开卡记录
		var openRecord models.HlpayCardOpenRecord
		if err := database.DB.Where("card_id = ?", cardIDStr).First(&openRecord).Error; err != nil {
			log.Printf("[HL Webhook] 未找到开卡记录 card_id=%s", cardIDStr)
			return nil
		}
		userID := openRecord.UserID
		matrixAccount := openRecord.MatrixAccount
		actualFeeAmount := openRecord.ActualFeeAmount

		// 2. 查找用户类型
		var user models.User
		if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
			log.Printf("[HL Webhook] 未找到用户 user_id=%d", userID)
			return nil
		}
		role := user.RoleID

		// 3. 判断开卡结果
		if notification.Status == "success" {
			// 3.1 修改余额
			switch role {
			case 2:
				// 更新hlpay_account_balances
				err := database.DB.Model(&models.HlPayAccountBalance{}).
					Where("owner_no = ?", matrixAccount).
					Update("real_time_balance", gorm.Expr("real_time_balance - ?", actualFeeAmount)).Error
				if err != nil {
					log.Printf("[HL Webhook] 更新hlpay_account_balances失败: %v", err)
				}
			case 3:
				// 更新hlpay_account_balances
				err1 := database.DB.Model(&models.HlPayAccountBalance{}).
					Where("owner_no = ?", matrixAccount).
					Update("real_time_balance", gorm.Expr("real_time_balance - ?", actualFeeAmount)).Error
				if err1 != nil {
					log.Printf("[HL Webhook] 更新hlpay_account_balances失败: %v", err1)
				}
				// 更新master_accounts
				err2 := database.DB.Model(&models.MasterAccount{}).
					Where("user_id = ?", userID).
					Update("balance", gorm.Expr("balance - ?", actualFeeAmount)).Error
				if err2 != nil {
					log.Printf("[HL Webhook] 更新master_accounts失败: %v", err2)
				}
			case 5:
				// 更新sub_accounts
				err := database.DB.Model(&models.SubAccount{}).
					Where("user_id = ?", userID).
					Update("balance", gorm.Expr("balance - ?", actualFeeAmount)).Error
				if err != nil {
					log.Printf("[HL Webhook] 更新sub_accounts失败: %v", err)
				}
			}
			// 3.2 发送开卡成功通知
			title := "开卡成功"
			// 将decimal.Decimal转换为float64进行格式化
			feeAmount, _ := actualFeeAmount.Float64()
			content := fmt.Sprintf("您的卡片（ID: %s）已成功开卡，费用 %.2f 已扣除。", cardIDStr, feeAmount)
			jsonData, _ := json.Marshal(notification.RawData)

			// 获取通知类型ID
			var notificationTypeModel models.NotificationType
			if err := database.DB.Where("code = ?", "CARD").First(&notificationTypeModel).Error; err != nil {
				log.Printf("[HL Webhook] 获取通知类型失败: %v", err)
				// 如果获取失败，使用默认值1
				notificationTypeModel.ID = 1
			}

			userNotification := &models.Notification{
				UserID:    userID,
				TypeID:    int64(notificationTypeModel.ID),
				Title:     title,
				Content:   content,
				Data:      models.JSON(jsonData),
				Status:    "UNREAD",
				CreatedAt: time.Now(),
			}
			if err := database.DB.Create(userNotification).Error; err != nil {
				log.Printf("[HL Webhook] 创建开卡成功通知失败: %v", err)
			} else {
				log.Printf("[HL Webhook] 已为用户 %d 发送开卡成功通知", userID)
			}
		} else if notification.Status == "fail" {
			// 只发开卡失败通知
			title := "开卡失败"
			content := fmt.Sprintf("您的卡片（ID: %s）开卡失败，未扣除余额，请稍后重试。", cardIDStr)
			jsonData, _ := json.Marshal(notification.RawData)

			// 获取通知类型ID
			var notificationTypeModel models.NotificationType
			if err := database.DB.Where("code = ?", "CARD").First(&notificationTypeModel).Error; err != nil {
				log.Printf("[HL Webhook] 获取通知类型失败: %v", err)
				// 如果获取失败，使用默认值1
				notificationTypeModel.ID = 1
			}

			userNotification := &models.Notification{
				UserID:    userID,
				TypeID:    int64(notificationTypeModel.ID),
				Title:     title,
				Content:   content,
				Data:      models.JSON(jsonData),
				Status:    "UNREAD",
				CreatedAt: time.Now(),
			}
			if err := database.DB.Create(userNotification).Error; err != nil {
				log.Printf("[HL Webhook] 创建开卡失败通知失败: %v", err)
			} else {
				log.Printf("[HL Webhook] 已为用户 %d 发送开卡失败通知", userID)
			}
		}
		return nil
	default:
		log.Printf("[HL Webhook] 未知事件类型: %s", notification.EventType)
		return nil
	}
}

// handleHLTransaction 处理海连交易通知
// 只创建用户通知，不保存交易记录
func (s *WebhookService) handleHLTransaction(notification HLWebhookNotification, transactionType string) error {
	log.Printf("[HL Webhook] 处理%s通知: 交易ID=%s, 金额=%.2f %s",
		transactionType, notification.Data.ID.String(), notification.Data.Amount, notification.Data.Currency)

	// 获取用户ID（通过卡片ID查找）
	var userCard models.UserCard
	cardIDStr := notification.Data.CardID.String()
	if err := database.DB.Where("card_id = ?", cardIDStr).First(&userCard).Error; err != nil {
		log.Printf("[HL Webhook] 警告: 未找到卡片 card_id=%s", cardIDStr)
		return nil // 继续处理，不返回错误
	}

	// 获取用户信息
	var user models.User
	if err := database.DB.Where("id = ?", userCard.UserID).First(&user).Error; err != nil {
		log.Printf("[HL Webhook] 警告: 未找到用户 user_id=%d", userCard.UserID)
		return nil
	}

	// 海连webhook只创建用户通知，不保存交易记录
	log.Printf("[HL Webhook] 创建用户通知，交易ID: %s", notification.Data.ID.String())

	// 创建用户通知
	if err := s.createHLUserNotification(user.ID, notification); err != nil {
		log.Printf("[HL Webhook] 警告: 创建用户通知失败: %v", err)
		return fmt.Errorf("创建用户通知失败: %v", err)
	}

	return nil
}

// createHLUserNotification 创建海连用户通知
func (s *WebhookService) createHLUserNotification(userID int64, notification HLWebhookNotification) error {
	// 获取通知类型ID
	var notificationTypeModel models.NotificationType
	notificationType := "TRANSACTION"
	if err := database.DB.Where("code = ?", notificationType).First(&notificationTypeModel).Error; err != nil {
		return fmt.Errorf("获取通知类型失败: %v", err)
	}

	// 构建通知内容
	title, content := s.buildHLNotificationContent(notification)

	// 将 RawData 转换为 JSON
	jsonData, err := json.Marshal(notification.RawData)
	if err != nil {
		return fmt.Errorf("序列化通知数据失败: %v", err)
	}

	// 创建通知记录
	userNotification := &models.Notification{
		UserID:    userID,
		TypeID:    int64(notificationTypeModel.ID),
		Title:     title,
		Content:   content,
		Data:      models.JSON(jsonData),
		Status:    "UNREAD",
		CreatedAt: time.Now(),
	}

	return database.DB.Create(userNotification).Error
}

// buildHLNotificationContent 构建海连通知内容
func (s *WebhookService) buildHLNotificationContent(notification HLWebhookNotification) (string, string) {
	var title, content string

	// 构建卡片信息：卡号（卡片ID）
	cardInfo := fmt.Sprintf("%s（%s）", notification.Data.CardNo, notification.Data.CardID.String())

	// 转换时间戳为可读时间格式
	var transactionTimeStr string
	if timestamp, err := notification.Data.TransactionTime.Int64(); err == nil {
		// 时间戳是毫秒级的，需要除以1000
		transactionTime := time.Unix(timestamp/1000, 0)
		transactionTimeStr = transactionTime.Format("2006-01-02 15:04:05")
	} else {
		transactionTimeStr = "未知时间"
	}

	switch notification.EventType {
	case "transaction:consumption":
		title = "消费交易通知"
		content = fmt.Sprintf("您的卡片%s发生消费交易，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	case "transaction:refund":
		title = "退款交易通知"
		content = fmt.Sprintf("您的卡片%s收到退款，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	case "transaction:transferin":
		title = "转入交易通知"
		content = fmt.Sprintf("您的卡片%s收到转入，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	case "transaction:transferout":
		title = "转出交易通知"
		content = fmt.Sprintf("您的卡片%s发生转出，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	case "transaction:credit":
		title = "授权交易通知"
		content = fmt.Sprintf("您的卡片%s发生授权交易，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	case "transaction:reversal":
		title = "交易撤销通知"
		content = fmt.Sprintf("您的卡片%s发生交易撤销，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.Amount, notification.Data.Currency, transactionTimeStr,
			notification.Data.TransactionNo, notification.Data.Detail)
	default:
		title = "交易通知"
		content = fmt.Sprintf("您的卡片%s发生%s交易，金额：%.2f %s，交易时间：%s，流水号：%s，详情：%s",
			cardInfo, notification.Data.TransactionType, notification.Data.Amount, notification.Data.Currency,
			transactionTimeStr, notification.Data.TransactionNo, notification.Data.Detail)
	}

	return title, content
}
